package org.edu.modules.base.util;

import java.io.File;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;

public class ServersMessage
{
    public Map queryServersMessage()
            throws UnknownHostException
    {
        String osName = System.getProperty("os.name");
        String osArch = System.getProperty("os.arch");
        String version = System.getProperty("os.version");


        InetAddress addr = InetAddress.getLocalHost();
        String ip = addr.getHostAddress();

        String localhost = addr.getHostName();

        SystemInfo systemInfo = new SystemInfo();

        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        try
        {
            TimeUnit.SECONDS.sleep(1L);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[oshi.hardware.CentralProcessor.TickType.NICE.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[oshi.hardware.CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[oshi.hardware.CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[oshi.hardware.CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[oshi.hardware.CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[oshi.hardware.CentralProcessor.TickType.USER.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[oshi.hardware.CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[oshi.hardware.CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[oshi.hardware.CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;

        String cpuUsage = new DecimalFormat("#.##%").format(1.0D - idle * 1.0D / totalCpu);

        GlobalMemory memory = systemInfo.getHardware().getMemory();

        long totalMemory = memory.getTotal();

        long residueMemory = memory.getAvailable();

        String memoryUsage = new DecimalFormat("#.##%").format((totalMemory - residueMemory) * 1.0D / totalMemory);

        String diskUsage = "";
        if ((!"".equals(osName)) && (osName != null) && (osName.contains("Linux")))
        {
            File diskPartition = new File("/");

            long totalCapacity = diskPartition.getTotalSpace();

            long usableSpace = diskPartition.getUsableSpace();
            diskUsage = new DecimalFormat("#.##%").format(usableSpace * 1.0D / totalCapacity);

            InetAddress inetAddress = getCurrentIp();
            ip = inetAddress.getHostAddress();
        }
        else
        {
            File diskPartition = new File("C:");

            long totalCapacity = diskPartition.getTotalSpace();

            long freePartitionSpace = diskPartition.getFreeSpace();

            long usablePartitionSpace = diskPartition.getUsableSpace();

            diskUsage = new DecimalFormat("#.##%").format(freePartitionSpace * 1.0D / totalCapacity);
        }
        Map map = new HashMap();
        map.put("osName", osName);
        map.put("osArch", osArch);
        map.put("version", version);
        map.put("localhost", localhost);
        map.put("ip", ip);
        map.put("cpuUsage", cpuUsage);
        map.put("memoryUsage", memoryUsage);
        map.put("diskUsage", diskUsage);
        return map;
    }

    public static InetAddress getCurrentIp()
    {
        try
        {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements())
            {
                NetworkInterface ni = (NetworkInterface)networkInterfaces.nextElement();
                Enumeration<InetAddress> nias = ni.getInetAddresses();
                while (nias.hasMoreElements())
                {
                    InetAddress ia = (InetAddress)nias.nextElement();
                    if ((!ia.isLinkLocalAddress()) && (!ia.isLoopbackAddress()) && ((ia instanceof Inet4Address))) {
                        return ia;
                    }
                }
            }
        }
        catch (SocketException e)
        {
            e.printStackTrace();
        }
        return null;
    }
}
